\chapter{相关概念基础}
\label{charp:science}
\section{区块链}
区块链就是一个个数据块依照时间顺序连接而成的链状数据结构，
这些数据区块环环相扣，每个区块都保存上一个区块的hash值，
保证已经固化的每个区块不能被篡改。
每台运行区块链的客户端节点相互通信组成了整个区块链，
每个节点之间通过共识算法\cite{吴璨2019分布式消息系统研究综述}
达成整个网络链的一致性。
只要网络中还存在一台节点，整个区块链网络就能正常运行。
只要网络中存在的恶意节点不超过一定比例，
即可让区块链正确运行。
例如：在POW共识算法下只要恶意节点的算力不超过$50\%$
就可以保证整个区块链的正常运行。
总的来说，区块链具有以下特点：
\xuhaotype[6]
\xuhao 数据不可篡改。
\xuhao 去中心化\cite{何蒲2017区块链技术与应用前瞻综述}。
\resetxuhao
基于以上特点，区块链可以解决现有的很多数据信任问题。

另外区块链可以分为三大类，
公有区块链、联盟区块链以及私有区块链\cite{邵奇峰2018区块链技术}。
其中私有区块链主要用于区块链应用的测试；
联盟区块链是只有特定的节点才能参与到共识过程，
任何人都可以通过联盟区块链开放的API调用区块链的接口，
主要用于企业及企业联盟的内部；
公有区块链是任何人都可参与到共识过程，
以比特币\cite{bohme2015bitcoin}\cite{nakamoto2008bitcoin}
为代表的各大虚拟数字货币均是基于公有区块链的。

\section{智能合约}
智能合约是一种计算机程序实现的协议\cite{2018Smart}，
是一种为了处理区块链上的信息传播方式、
验证信息合法性以及执行合约中预定代码的计算机协议。
智能合约允许任何实体在没有第三方的情况下执行可信的交易，
这些交易同样是是可被追踪并且不可逆转的。
智能合约的出现使得永久不变的去中心化应用程序的部署变成可能。
智能合约的出现为区块链注入了新的活力，
使得区块链应用如雨后春笋般快速发展起来，
是继区块链之后的又一大技术革新。

\section{以太坊和Solidity}
以太坊是一个去中心化的公共开源区块链，
它附带有智能合约功能，
并且他的智能合约开发语言是图灵完备的Solidity
\cite{dannen2017introducing}语言。
以太坊中有2种账户：外部账户和合约账户。
其中外部账户是普通用户所拥有的账户，
它的地址由以太坊公钥通过keccak256算法产生确定，
而以太坊公钥通过对以太坊私钥运用椭圆曲线算法产生。
而合约账户不仅拥有外部账户的所有特征，
它还存储了合约代码也就是编译后产生的字节码文件。
另外，与以太坊上转账类似，
Solidity合约的部署也是通过转账来实现的，
只是转账目标地址为0x0开头的，
矿工在看到该地址之后就会将输入数据中的程式码部署到区块链之上，
并生成一个合约地址。

\section{密码学}
现代的密码学主要包含对称加密算法、
非对称加密算法、哈希摘要算法\cite{曾清扬2019DES}。
其中现代加密算法要求算法的实现细节完全公开，
加密之后数据安全性的保证应该完全依赖于密钥的安全性。
出于本文研究内容的考虑，在此只介绍非对称加密和哈希摘要算法。

\subsection{非对称加密}
非对称加密技术通过公私秘钥对实现，
而公钥与私钥则是通过非对称加密算法成对产生，
常见的非对称加密算法包括RSA、椭圆曲线算法，
而算法产生的公钥是可以公开的，
私钥是不可公开的，必须由用户自己严加看管。
在数据加解密的领域，
通过公钥对数据进行加密，
而非对称加密算法保证了只有对应的私钥能够解密；
而在数字签名的领域，通过私钥对数据签名，
而非对称加密算法保证了只有对应公钥能够验证签名。
以上即为熟悉的：
“公钥加密，私钥解密；私钥签名，公钥验证”。

在以太坊中，
主要通过椭圆曲线数字签名算法（ECDSA）
实现非对称加密的相关内容。

\subsection{哈希摘要算法}
摘要算法也就是哈希算法，
是一种将不固定长度的原始数据
通过哈希计算将其转换成一串固定长度的字符串的一种算法，
产生的固定长度的字符串被称为原始数据的摘要。
并且既是原始数据有单个比特的变动，摘要后的结果也会有巨大的差异。

SHA（Secure Hash Algorithm，安全散列算法）
是一个密码散列函数家族，
而SHA256是实现SHA标准且更加注重安全的一种算法，
它可以将原始的数据信息通过Hash摘要变成一个256比特也就是32字节的哈希值。


\section{Merkle树}
\begin{figure}[h]
  \centerline{\includegraphics[scale=0.3]{merkletreejs.png}}
  \caption{Merkle树实例}
  \label{fig:Merkle Tree}
\end{figure}

Merkle树\cite{szydlo2004merkle}是一种基于 SHA256 哈希值的树形数据结构，
如图\ref{fig:Merkle Tree} 所示，它通过层层计算与Hash，将5个数据块映射为了一个固定长度的字符串。
Merkle树结构的具体特点有：
\xuhaotype[6]
\xuhao Merkle树一般为二叉树，但有时也可以是多叉树。但无论是几叉树，它都具有树结构的所有特点；
\xuhao 叶结点的数值是单个数据块进行哈希运算之后的结果；
\xuhao 如下式\ref{con:hash}所示，非叶子结点的值
均是其左子结点和右子节点经过某种运算后的得到的结果再进行哈希得到的结果值；
另外对于单亲节点则直接哈希，如此这样层层子节点不断往上哈希得到父节点，
最终收敛到一个哈希值，该哈希值通常被称作根哈希。
\resetxuhao

\begin{equation}
  Node value = Hash(leftChild+rightChild)
  \label{con:hash}
\end{equation}

\section{Merkle树的选择性披露}
\label{sec:Merkle proof}
\begin{figure}[h]
  \centerline{\includegraphics[scale=0.7]{merkletree_proof.png}}
  \caption{Merkle 树选择性披露实例}
  \label{fig:Merkle Tree Proof}
\end{figure}
在选择性披露时，如我们需要披露生日的信息而隐藏姓名、住址以及民族的信息，
这时我们只需要Hash1与Hash34的值即可，
为方便后文叙述，再此将数组[Hash1，Hash34]称为Proof数组\cite{ramabaja2020compact}，
在拥有Proof数组和披露信息的情况下即可根据式子
\ref{con:hash}重建不完全的Merkle树，
并得到具有相同值的Merkle Root。
所以我们将Proof数组和披露信息生日
告诉给第三方，这样他们就能重建这棵不完整的Merkle树，
将得到的Merkle Root的值与原来的值进行比对，
从而判断是用户是否修改披露信息和Proof数组的值。

\begin{figure}[h]
  \centerline{\includegraphics[scale=0.7]{merkletree_salt_proof.png}}
  \caption{Merkle 树和Salt Seed实例}
  \label{fig:Merkle Tree Salt Proof}
\end{figure}
上述过程会引入两个安全性问题，即：
\xuhaotype[6]
\xuhao 在恶意用户修改披露值后通过Hash碰撞
构造出Proof数组仍可让Merkle Root的值相同，
即验证方不知道用户提交的是修改后的值。
\xuhao 对于验证方来说，可能根据Hash值
还原出用户不想披露的隐私，即验证方知道了用户不想披露的值。
\resetxuhao
问题一是考虑身份信息验证方的利益，防止恶意用户伪造身份信息；
问题二是考虑提供身份信息的用户的利益，防止额外的身份信息泄露。
两个问题都基于同一个问题即Hash的安全性，
即不能够根据Hash值得到其原来的值，
对于该问题的研究超出了本文的讨论范围，
在此主要讨论本文出现的涉及该问题的解决方案。

在对于一些有限集合来说Hash的安全是没有保障的，
如在我们示例中的民族属性是一个56个元素的有限集合，
用户不想披露民族信息，但是Proof数组中包含了民族信息的Hash值，
攻击者通过暴力破解的方式也可以知道民族属性原来的值，
即通过依次Hash计算这56个元素并将结果与
Hash1对比即可得到民族的原值，
故我们需要为将民族属性的取值增多使攻击者难以暴力破解。
具体即为我们通过引入Salt Seed，
基于这个Salt Seed生成N个序列
（N取决与我们默克尔树的叶子节点数），
因为我们的种子是随机生成的，
所以我们可以认为这个序列也是随机的。
在选取序列生成函数时，最简单的办法就是用哈希函数，
不断的对序列最后一个值进行Hash运算，
从而得到下一个数据，将该数据加入序列。
至此我们即完成了用户的选择性披露，
并且保证了选择性披露的安全性。

\section{DID数字身份}
DID是由W3C提出的一种数字身份标识标准，
它在整个标准下具有全局唯一性、
可解析性以及加密可验证性。
DID文档是DID的详细表述，它是一种JSON格式的文档，
由DID标识符、公钥、认证和服务等属性组成，它详细记录了DID所需要的所有数据。
由于DID文档中的其他属性种类繁多比较复杂，
在本节只针对本文需要使用的部分做相应的属性介绍。
\subsection{DID标识符}

\begin{equation}
  did: eth:0xb85cA0627Fc1A08eBc41378d2328b9EA70512Db0
  \label{con:didSymbol}
\end{equation}

DID标识符是一个DID文档的唯一标识，
，实例\ref{con:didSymbol}是一个在本文实现过程中使用到的DID的标识符，
它是由 3 部分组成的字符串：
\xuhaotype[6]
\xuhao URL 方法符号，在我们的例子中为did；
\xuhao DID Method（DID方法名称），在我们的例子中为eth；
\xuhao 具体标识符，每个实体所对应的整个具体的DID标识符应该保证它在全局的唯一性。
在我们的例子中是一个以太坊地址0xb85cA0627Fc1A08eBc41378d2328b9EA70512Db0。

\subsection{公钥}
公钥，即为该DID文档对应的公钥，
根据前文所述的公私钥加密体系，
公钥可以标识签名是否为拥有该DID身份的用户所签，
是整个数字身份管理系统中必不可少的部分。

\section{本章小结}
本章主要介绍了以太坊的相关基础以及
数字身份管理中设计的密码学基础，
着重介绍了Merkle树的选择性披露部分，
本文很大一部分工作将围绕Merkle树的选择性披露展开。